import tkinter as tk
from tkinter import messagebox
import cv2
import numpy as np
import pyautogui
import threading
import os
import time
from datetime import datetime
from PIL import Image, ImageTk, ImageDraw, ImageFont


class ScreenRecorderWithPreview:
    def __init__(self, root):
        self.root = root
        self.root.title("屏幕录制工具")
        self.root.geometry("500x450")
        self.root.resizable(False, False)
        self.root.configure(bg="#f0f0f0")

        # 初始化变量
        self.recording = False
        self.paused = False
        self.output_folder = os.path.join(os.path.expanduser("~"), "Desktop", "录屏文件")
        self.video_writer = None
        self.thread = None
        self.preview_thread = None
        self.start_time = None
        self.pause_time = 0
        self.last_frame = None

        # 创建UI
        self.create_widgets()

        # 确保输出文件夹存在
        if not os.path.exists(self.output_folder):
            os.makedirs(self.output_folder)

        # 启动预览更新
        self.update_preview()

    def create_widgets(self):
        # 标题
        title_label = tk.Label(
            self.root,
            text="屏幕录制工具",
            font=("微软雅黑", 16),
            bg="#f0f0f0"
        )
        title_label.pack(pady=10)

        # 预览区域
        self.preview_frame = tk.Frame(self.root, bg="black", height=240, width=426)
        self.preview_frame.pack(pady=5)
        self.preview_frame.pack_propagate(False)  # 固定预览区域大小

        self.preview_label = tk.Label(self.preview_frame, bg="black")
        self.preview_label.pack(fill="both", expand=True)

        # 状态栏
        status_frame = tk.Frame(self.root, bg="#f0f0f0")
        status_frame.pack(fill="x", padx=20, pady=10)

        self.status_label = tk.Label(
            status_frame,
            text="就绪",
            font=("微软雅黑", 10),
            bg="#f0f0f0",
            anchor="w"
        )
        self.status_label.pack(side="left")

        self.timer_label = tk.Label(
            status_frame,
            text="00:00:00",
            font=("微软雅黑", 10),
            bg="#f0f0f0",
            anchor="e"
        )
        self.timer_label.pack(side="right")

        # 控制按钮
        button_frame = tk.Frame(self.root, bg="#f0f0f0")
        button_frame.pack(pady=15)

        self.start_btn = tk.Button(
            button_frame,
            text="开始录制",
            command=self.start_recording,
            font=("微软雅黑", 12),
            bg="#4CAF50",
            fg="white",
            width=10,
            relief="flat"
        )
        self.start_btn.pack(side="left", padx=5)

        self.pause_btn = tk.Button(
            button_frame,
            text="暂停",
            command=self.toggle_pause,
            font=("微软雅黑", 12),
            bg="#FFC107",
            fg="black",
            width=10,
            relief="flat",
            state="disabled"
        )
        self.pause_btn.pack(side="left", padx=5)

        self.stop_btn = tk.Button(
            button_frame,
            text="停止录制",
            command=self.stop_recording,
            font=("微软雅黑", 12),
            bg="#F44336",
            fg="white",
            width=10,
            relief="flat",
            state="disabled"
        )
        self.stop_btn.pack(side="left", padx=5)

    def update_preview(self):
        if self.recording and not self.paused:
            try:
                screenshot = pyautogui.screenshot()
                self.last_frame = screenshot
            except:
                screenshot = Image.new("RGB", (800, 600), "black")
        else:
            if self.last_frame:
                screenshot = self.last_frame
            else:
                screenshot = Image.new("RGB", (800, 600), "black")
                draw = ImageDraw.Draw(screenshot)
                try:
                    font = ImageFont.truetype("arial.ttf", 24)
                except:
                    font = ImageFont.load_default()
                text = "屏幕预览区域"
                bbox = draw.textbbox((0, 0), text, font=font)
                w, h = bbox[2] - bbox[0], bbox[3] - bbox[1]
                draw.text(((800 - w) // 2, (600 - h) // 2), text, fill="white", font=font)

        # 调整预览大小
        screenshot = screenshot.resize((426, 240), Image.LANCZOS)

        # 显示预览
        self.preview_img = ImageTk.PhotoImage(screenshot)
        self.preview_label.configure(image=self.preview_img)

        # 每100ms更新一次预览
        self.root.after(100, self.update_preview)

    def update_timer(self):
        if self.recording and not self.paused:
            elapsed = time.time() - self.start_time - self.pause_time
            hours, remainder = divmod(elapsed, 3600)
            minutes, seconds = divmod(remainder, 60)
            self.timer_label.config(text=f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}")
        self.root.after(1000, self.update_timer)

    def start_recording(self):
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"录屏_{timestamp}.mp4"
        self.output_path = os.path.join(self.output_folder, filename)

        screen_size = pyautogui.size()
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        self.video_writer = cv2.VideoWriter(self.output_path, fourcc, 15.0, screen_size)

        self.recording = True
        self.paused = False
        self.start_time = time.time()
        self.pause_time = 0
        self.status_label.config(text="录制中...")
        self.start_btn.config(state="disabled")
        self.pause_btn.config(state="normal")
        self.stop_btn.config(state="normal")

        self.thread = threading.Thread(target=self.record_screen)
        self.thread.daemon = True
        self.thread.start()

        self.update_timer()

    def toggle_pause(self):
        if self.paused:
            # 继续录制
            self.pause_time += time.time() - self.pause_start_time
            self.paused = False
            self.pause_btn.config(text="暂停")
            self.status_label.config(text="录制中...")
        else:
            # 暂停录制
            self.pause_start_time = time.time()
            self.paused = True
            self.pause_btn.config(text="继续")
            self.status_label.config(text="已暂停")

    def record_screen(self):
        while self.recording:
            if not self.paused:
                try:
                    screenshot = pyautogui.screenshot()
                    frame = np.array(screenshot)
                    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
                    self.video_writer.write(frame)
                except Exception as e:
                    print(f"录制错误: {e}")
            time.sleep(0.066)  # ~15fps

    def stop_recording(self):
        self.recording = False
        if self.thread:
            self.thread.join()
        if self.video_writer:
            self.video_writer.release()

        self.status_label.config(text="录制完成")
        self.start_btn.config(state="normal")
        self.pause_btn.config(state="disabled", text="暂停")
        self.stop_btn.config(state="disabled")
        messagebox.showinfo("完成", f"视频已保存到:\n{self.output_path}")

    def on_close(self):
        if self.recording:
            if messagebox.askokcancel("退出", "正在录制中，确定要退出吗？"):
                self.stop_recording()
                self.root.destroy()
        else:
            self.root.destroy()
if __name__ == "__main__":
    root = tk.Tk()
    app = ScreenRecorderWithPreview(root)
    root.protocol("WM_DELETE_WINDOW", app.on_close)
    root.mainloop()